﻿#include "timer.h"
#include "debug.h"


/**
 * @brief 定时器0配置 通道0测量信号波形
 */
void Timer0Config(void)
{
    timer_parameter_struct timer_initpara;
    timer_ic_parameter_struct timer_icintpara;

    rcu_periph_clock_enable(RCU_TIMER0);

    timer_deinit(TIMER0);

    /* time base configuration */
    timer_initpara.prescaler         = TIMER0_PSC - 1;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = 65535;
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
    timer_initpara.repetitioncounter = 0;
    timer_init(TIMER0, &timer_initpara);

    /* configure the channel to input mode */
    timer_icintpara.icpolarity  = TIMER_IC_POLARITY_RISING;
    timer_icintpara.icselection = TIMER_IC_SELECTION_DIRECTTI;
    timer_icintpara.icprescaler = TIMER_IC_PSC_DIV1;
    timer_icintpara.icfilter    = 0x7;
    timer_input_pwm_capture_config(TIMER0, TIMER_CH_0, &timer_icintpara);

    /* slave mode selection: TIMER2 */
    timer_input_trigger_source_select(TIMER0, TIMER_SMCFG_TRGSEL_CI0FE0);
    timer_slave_mode_select(TIMER0, TIMER_SLAVE_MODE_RESTART);

    /* TIMER0 update DMA request enable */
    timer_dma_enable(TIMER0, TIMER_DMA_CH0D);
    timer_dma_enable(TIMER0, TIMER_DMA_CH1D);

    /* auto-reload preload enable */
    timer_auto_reload_shadow_enable(TIMER0);

    /* TIMER2 counter enable */
    timer_enable(TIMER0);
}

/**
 * @brief 定时器0 GPIO配置
 */
void Timer0GpioConfig(void)
{
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_AF);

    gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_8);
    gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOA, GPIO_PIN_SOURCE_8);
    exti_init(EXTI_8, EXTI_INTERRUPT, EXTI_TRIG_RISING);
    exti_interrupt_enable(EXTI_8);
    nvic_irq_enable(EXTI5_9_IRQn, 5, 0);
}

/**
 * @brief 定时器1配置 channel0触发ADC0采样
 */
void Timer1Config(void)
{
    timer_oc_parameter_struct timer_ocintpara;
    timer_parameter_struct timer_initpara;

    rcu_periph_clock_enable(RCU_TIMER1);

    /* deinit a timer */
    timer_deinit(TIMER1);
    /* initialize TIMER init parameter struct */
    timer_struct_para_init(&timer_initpara);
    /* TIMER1 configuration */
    timer_initpara.prescaler         = 107;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = 99;
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
    timer_initpara.repetitioncounter = 0;
    timer_init(TIMER1, &timer_initpara);

    /* CH0 configuration in PWM mode1 */
    timer_ocintpara.ocpolarity  = TIMER_OC_POLARITY_HIGH;
    timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
    timer_channel_output_config(TIMER1, TIMER_CH_1, &timer_ocintpara);

    timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_1, 9);
    timer_channel_output_mode_config(TIMER1, TIMER_CH_1, TIMER_OC_MODE_PWM1);
    timer_channel_output_shadow_config(TIMER1, TIMER_CH_1, TIMER_OC_SHADOW_DISABLE);

    /* enable the TIMER */
    timer_enable(TIMER1);
}

/**
 * @brief 定时器2配置 通道1发生1KHz方波
 */
void Timer2Config(void)
{
    timer_parameter_struct timer_initpara;
    timer_oc_parameter_struct timer_ocintpara;

    rcu_periph_clock_enable(RCU_TIMER2);

    timer_deinit(TIMER2);

    /* time base configuration */
    timer_struct_para_init(&timer_initpara);
    timer_initpara.prescaler         = 107;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = 999;
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
    timer_initpara.repetitioncounter = 0;
    timer_init(TIMER2, &timer_initpara);

    /* output compare config */
    timer_ocintpara.ocpolarity  = TIMER_OC_POLARITY_HIGH;
    timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
    timer_channel_output_config(TIMER2, TIMER_CH_1, &timer_ocintpara);

    timer_channel_output_pulse_value_config(TIMER2, TIMER_CH_1, 499);
    timer_channel_output_mode_config(TIMER2, TIMER_CH_1, TIMER_OC_MODE_PWM0);
    timer_channel_output_shadow_config(TIMER2, TIMER_CH_1, TIMER_OC_SHADOW_DISABLE);

    /* enable auto-reload shadow function */
    timer_auto_reload_shadow_enable(TIMER2);

    /* enable the TIMER */
    timer_enable(TIMER2);
}

/**
 * @brief 定时器2的GPIO配置
 */
void Timer2GpioConfig(void)
{
    rcu_periph_clock_enable(RCU_GPIOA);

    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
}

/**
 * @brief 定时器3配置 通道2输出占空比可调的pwm波 通道3输出PWM波 更新中断开启ADC采样
 */
void Timer3Config(void)
{
    timer_parameter_struct timer_initpara;
    timer_oc_parameter_struct timer_ocintpara;

    rcu_periph_clock_enable(RCU_TIMER3);

    timer_deinit(TIMER3);

    /* time base configuration */
    timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection = TIMER_COUNTER_UP;
    timer_initpara.prescaler = 107;
    timer_initpara.period = 99;
    timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
    timer_initpara.repetitioncounter = 0;
    timer_init(TIMER3, &timer_initpara);

    /* configure the channel 2 output function */
    timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
    timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
    timer_channel_output_config(TIMER3, TIMER_CH_2, &timer_ocintpara);

    timer_channel_output_pulse_value_config(TIMER3, TIMER_CH_2, 50);
    timer_channel_output_mode_config(TIMER3, TIMER_CH_2, TIMER_OC_MODE_PWM0);
    timer_channel_output_shadow_config(TIMER3, TIMER_CH_2, TIMER_OC_SHADOW_DISABLE);

    /* configure the channel 3 output function */
    timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
    timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
    timer_channel_output_config(TIMER3, TIMER_CH_3, &timer_ocintpara);

    timer_channel_output_pulse_value_config(TIMER3, TIMER_CH_3, 19);
    timer_channel_output_mode_config(TIMER3, TIMER_CH_3, TIMER_OC_MODE_PWM0);
    timer_channel_output_shadow_config(TIMER3, TIMER_CH_3, TIMER_OC_SHADOW_DISABLE);

    /* enable auto-reload shadow function */
    timer_auto_reload_shadow_enable(TIMER3);

    /* enable the TIMER */
    timer_enable(TIMER3);
}

/**
 * @brief 定时器3 GPIO配置 通道2发生PWM波 通道3输出PWM波
 */
void Timer3GpioConfig(void)
{
    rcu_periph_clock_enable(RCU_GPIOB);

    gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8 | GPIO_PIN_9);
}
